import cv2
import numpy as np

# 加载图像
image_path = r'd:\tmp\full.png'
image = cv2.imread(image_path)

# 将图像转换为 RGB 格式（OpenCV 默认是 BGR）
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# 定义按钮的颜色范围
button_color_lower = np.array([210, 210, 210])  # 按钮上的大部分颜色 (222,223,221)
button_color_upper = np.array([230, 230, 230])  # 允许一定的颜色偏差

# 创建掩码，提取按钮区域
mask = cv2.inRange(image_rgb, button_color_lower, button_color_upper)

# 去除噪声（可选）
kernel = np.ones((5, 5), np.uint8)
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)  # 开运算去除小噪声
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel)  # 闭运算填充小孔洞

# 查找轮廓
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 过滤轮廓
min_area = 500  # 最小面积阈值
buttons = []
for cnt in contours:
    area = cv2.contourArea(cnt)
    if area > min_area:
        buttons.append(cnt)

# 按从上到下、从左到右排序按钮
# 获取每个按钮的中心点
button_centers = []
for cnt in buttons:
    x, y, w, h = cv2.boundingRect(cnt)
    center_x = x + w // 2
    center_y = y + h // 2
    button_centers.append((center_x, center_y, cnt))

# 先按 y 坐标（从上到下）排序，再按 x 坐标（从左到右）排序
button_centers_sorted = sorted(button_centers, key=lambda c: (c[1], c[0]))

# 绘制轮廓并计算中心点
button_id = 1  # 按钮编号
for center_x, center_y, cnt in button_centers_sorted:
    # 获取按钮的边界框
    x, y, w, h = cv2.boundingRect(cnt)
    
    # 绘制边界框
    cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)
    
    # 绘制中心点
    cv2.circle(image, (center_x, center_y), 5, (0, 0, 255), -1)
    
    # 在中心点绘制按钮编号
    cv2.putText(image, str(button_id), (center_x - 10, center_y + 10),
                cv2.FONT_HERSHEY_SIMPLEX, 0.9, (255, 0, 0), 2)
    
    # 输出按钮的区域信息和中心点坐标
    print(f"Button {button_id}: Region (x={x}, y={y}, w={w}, h={h}), Center (x={center_x}, y={center_y})")
    
    # 增加按钮编号
    button_id += 1

# 显示结果
cv2.imshow('Detected Buttons', image)
cv2.waitKey(0)
cv2.destroyAllWindows()